/*
 * @Author: zhang 
 * @Date: 2019-10-08 09:53:06 
 * @Last Modified by: zhang
 * @Last Modified time: 2019-10-08 10:21:24
 */

const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'

function MyPromise(fn) {
    const _this = this
    _this.state = PENDING
    _this.value = null
    _this.resolvedCallbacks = []
    _this.rejectedCallbacks = []

    function resolve(value) {
        if (_this.state === PENDING) {
            _this.state = RESOLVED
            _this.value = value
            _this.rejectedCallbacks.map(cb => cb(_this.value))
        }
    }

    function reject(value) {
        if (_this.state === PENDING) {
            _this.state = REJECTED
            _this.value = value
            _this.rejectedCallbacks.map(cb => cb(_this.value))
        }
    }

    try {
        fn(resolve, reject)
    } catch (e) {
        reject(e)
    }
}

MyPromise.prototype.then = function(onFulfilled, onRejected) {
    const _this = this
    onFulfilled = typeof onFulfilled === 'function'
        ? onFulfilled 
        : v => v
    
    onRejected = typeof onRejected === 'function'
        ? onRejected
        : r => {
            throw r
        }
    
    if (_this.state === PENDING) {
        _this.resolvedCallbacks.push(onFulfilled)
        _this.rejectedCallbacks.push(onRejected)
    }

    if (_this.state === RESOLVED) {
        onFulfilled(_this.value)
    }

    if (_this.state === REJECTED) {
        onRejected(_this.value)
    }
}